import {GLOBAL_LOGIN_TOKEN, WORK_LOGIN_TOKEN} from "@/utils/const";
import {getItem, removeItem} from "@/utils/storage";
import {generateSign, isEmpty, showToast} from "@/utils/utils";
import Api from "@/utils/api";

/**
 * 请求的 content-type 类型为 application/x-www-form-urlencoded 的地址集合
 */
const contentTypeList = [Api.MergePartFile, Api.CancelUpload, Api.PrizeDoOrder]

/**
 * 请求参数需要前面的接口地址集合
 * 1、兑换奖品；2、任务审核通过增加积分；3、线下任务上传；
 */
const signList = [Api.DoPrize, Api.DoTask, Api.OffingTaskUpload]

/**
 * GET网络请求
 * message不为空时有加载框
 */
export function getRequest(url, params = {}, message = '') {
  return baseRequestLoading(url, params, 'GET', message)
}

/**
 * POST网络请求
 * message不为空时有加载框
 */
export function postRequest(url, params = {}, message = '') {
  return baseRequestLoading(url, params, 'POST', message)
}

/**
 * 文件上传网络请求（只支持图片和视频上传）
 * message不为空时有加载框
 */
export function uploadFileRequest(url, filePath, params = {}, message = '', name='file') {
  return uploadingFiles(url, filePath, params, message, name)
}

/**
 * 展示进度条的网络请求
 * url:网络请求的url
 * params:请求参数
 * message:进度条的提示信息
 * success:成功的回调函数
 * fail：失败的回调
 */
function baseRequestLoading(url, params, method, message) {
  // 添加token参数到请求参数中
  const token = getItem(GLOBAL_LOGIN_TOKEN)
  if (token.length > 0) {
    params['token'] = token
  }

  // 打印输出请求参数
  console.log('请求参数：', params)
  if (!isEmpty(message)) {
    // 显示加载视图
    uni.showLoading({
      title: message, mask: true
    })
  }
  return new Promise(function (resolve, reject) {
    /**
     * content-type类型
     * 1、application/json 会对数据进行 JSON 序列化
     * 2、application/x-www-form-urlencoded  会将数据转换成 query string
     * */

    /** 智慧办公鉴权token处理 */
    let authorization = ''
    let header = {
      'content-type': 'application/json'
    }
    console.log(url)
    if (!isEmpty(getItem(WORK_LOGIN_TOKEN))) {
      if (url !== Api.WorkLogin || url !== Api.SaveCommonLog) {
        authorization = getItem(WORK_LOGIN_TOKEN)
        header['Authorization'] = authorization
      }
      if (contentTypeList.includes(url)) {
        header['content-type'] = 'application/x-www-form-urlencoded'
      }
    }

    // 签名校验
    if (signList.includes(url)) {
      header['sign'] = generateSign(params)
    }

    uni.request({
      url: url,
      data: params,
      method: method,
      header
    }).then(data => {
      /**
       * Vue2 对部分 API 进行了 Promise 封装，返回数据的第一个参数是错误对象，第二个参数是返回数据。
       * 此时使用 catch 是拿不到报错信息的，因为内部对错误进行了拦截。
       *
       * data为一个数组
       * 数组第一项为错误信息 即为 fail 回调
       * 第二项为返回数据
       */
      console.log(data);
      // const [err, res] = data;

      /**
       * {
       * "successFlg": 1,
       * "errorCode": 1000,
       * "errorMsg": "操作成功",
       * "dateSize": null,
       * "data": 1 //返回数据
       * }
       */

      // 隐藏加载提示框
      if (!isEmpty(message)) {
        uni.hideLoading()
      }

      const result = data.data
      if (!isEmpty(result.successFlg)) {
        if (result.successFlg === 1) { // 请求成功
          if (result.errorCode === 1000) {
            resolve(result.data)
          }
        } else {
          switch (result.errorCode) {
            case 1005:  // 操作失败(创建任务失败会报错1005)
              if (url === Api.Login) {
                resolve(null)
              } else {
                if (!isEmpty(result.errorMsg)) {
                  showToast(result.errorMsg)
                } else {
                  showToast('数据获取失败！')
                }
              }
              break
            default:
              if (!isEmpty(result.errorMsg)) {
                showToast(result.errorMsg)
              } else {
                showToast('数据获取失败！')
              }
              break
          }
        }
      } else {
        if (result.code === 200) {
          resolve(result)
        } else if (result.code === 401) {
          uni.showModal({
            title: "温馨提示",
            content: "您的登录状态已过期或有人在别处登录，您可以继续留在该页面，或者重新登录!",
            confirmText: "重新登录",
            success: function (res) {
              if (res.confirm) {
                removeItem(WORK_LOGIN_TOKEN)
                uni.navigateBack({
                  delta: 1
                })
              } else if (res.cancel) {
                console.log('用户点击取消');
              }
            },
            fail: function (res) {
              removeItem(WORK_LOGIN_TOKEN)
              uni.navigateBack({
                delta: 1
              })
            }
          })
        } else {
          if (!isEmpty(result.msg)) {
            showToast(result.msg)
          } else {
            showToast('数据获取失败！')
          }
        }
      }
    }).catch(error => {
      // 隐藏加载提示框
      if (!isEmpty(message)) {
        uni.hideLoading()
      }
      showToast('数据获取失败！')
      reject(error)
      console.log(error)
    })
  })
}

/**
 * 展示进度条的文件上传请求
 * url:网络请求的url
 * filePath:文件地址
 * params:请求参数
 * message:进度条的提示信息
 * success:成功的回调函数
 * fail：失败的回调
 */
function uploadingFiles(url, filePath, params, message, name) {
  // 打印输出请求参数
  // console.log(params);
  if (!isEmpty(message)) {
    // 显示加载视图
    uni.showLoading({
      title: message, mask: true
    })
  }

  console.log('文件路径: ', filePath);

  return new Promise(function (resolve, reject) {
    /** 智慧办公鉴权token处理 */
    let authorization = ''
    if (!isEmpty(getItem(WORK_LOGIN_TOKEN))) {
      if (url !== Api.UploadPic) {
        authorization = getItem(WORK_LOGIN_TOKEN)
      }
    }

    uni.uploadFile({
      url: url,
      filePath: filePath,
      name: name,
      formData: params,
      header: {
        'Authorization': authorization
      }
    }).then(data => {
      /**
       * Vue2 对部分 API 进行了 Promise 封装，返回数据的第一个参数是错误对象，第二个参数是返回数据。
       * 此时使用 catch 是拿不到报错信息的，因为内部对错误进行了拦截。
       *
       * data为一个数组
       * 数组第一项为错误信息 即为 fail 回调
       * 第二项为返回数据
       */
      // const [err, res] = data;

      // 隐藏加载提示框
      if (!isEmpty(message)) {
        uni.hideLoading()
      }

      const result = JSON.parse(data.data)

      console.log(result)

      if (result["successFlg"] === 1) { // 请求成功
        if (result["errorCode"] === 1000) {
          resolve(result["data"])
        }
      } else {
        reject()
      }
    }).catch(error => {
      console.log(error);
      // 隐藏加载提示框
      if (!isEmpty(message)) {
        uni.hideLoading()
      }
      showToast('文件上传失败！')
      reject(error)
    })
  })
}
